/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.sistema.util.validacao;

import br.com.sistema.entidades.editor.Editor;
import br.com.sistema.infraestrutura.CFG;
import br.com.sistema.util.MultipartFormHandler;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;

/**
 *
 * @author Lauro
 */
public class ValidacaoUtil {

    private int status;
    private String mensagem;
    private int tipoMensagem = 0;
    private TipoRetorno tipoRetorno;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private MultipartFormHandler form;
    boolean redirecionarTelaPai = false;

    public void setMensagem(String mensagem) {
        this.mensagem = mensagem;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public ValidacaoUtil(TipoRetorno tipoRetorno, HttpServletRequest request, HttpServletResponse response) {
        this.tipoRetorno = tipoRetorno;
        this.request = request;
        this.response = response;
    }

    public ValidacaoUtil(TipoRetorno tipoRetorno, MultipartFormHandler form, HttpServletResponse response) {
        this.tipoRetorno = tipoRetorno;
        this.form = form;
        this.response = response;
    }

    public TipoRetorno getTipoRetorno() {
        return tipoRetorno;
    }

    public void setTipoRetorno(TipoRetorno tipoRetorno) {
        this.tipoRetorno = tipoRetorno;
    }

    public boolean isRedirecionarTelaPai() {
        return redirecionarTelaPai;
    }

    public void setRedirecionarTelaPai(boolean redirecionarTelaPai) {
        this.redirecionarTelaPai = redirecionarTelaPai;
    }

    public String getMensagem(String redirectTo) {
        if (tipoRetorno == TipoRetorno.RETORNO_MENSAGEM) {
            return getJavascriptMensagem(redirectTo);
        }

        if (tipoRetorno == TipoRetorno.RETORNO_TEXTO) {
            return getMensagemTexto(redirectTo);
        }

        if (tipoRetorno == TipoRetorno.RETORNO_PAGINA_HTML) {
            return getMensagemPaginaHTML(redirectTo);
        }

        if (tipoRetorno == TipoRetorno.RETORNO_AJAX) {
            try {
                //response.sendError(status, mensagem);
                response.setStatus(status);
                response.getWriter().write(mensagem);
            } catch (IOException ex) {
            }
        }
        return "";
    }

    private String getMensagemTexto(String redirectTo) {
        StringBuilder result = new StringBuilder();
        result.append("<div>").append(this.mensagem).append("</div>");
        if (redirectTo != null) {
            result.append("<div>Você será redirecionado...</div>");
            result.append("<em>Clique <a href='").append(redirectTo).append("'>aqui</a> se demorar muito!</em>");
            result.append("<script>");
            result.append("setTimeout(function() {window.location = '").append(redirectTo).append("'},3000);");
            result.append("</script>");
        }
        return result.toString();
    }

    private String getMensagemPaginaHTML(String redirectTo) {
        StringBuilder result = new StringBuilder();
        result.append("<head>");
        result.append("<script type='text/javascript' src='js/jqueryui/js/jquery-1.7.2.min.js'></script>");
        result.append("<script src='js/jqueryui/js/jquery-ui-1.8.20.custom.min.js' type='text/javascript'></script>");
        result.append("<link href='js/jqueryui/css/custom-theme/jquery-ui-1.8.20.custom.css' type='text/css' rel='stylesheet' />");
        result.append("<script src='js/uteis.js'></script>");
        result.append("<link rel='stylesheet' href='style.css' />");
        result.append("</head><body>");
        result.append(getJavascriptMensagem(redirectTo));
        result.append("</body>");
        return result.toString();
    }

    private String getJavascriptMensagem(String redirectTo) {
        if (this.status == HttpServletResponse.SC_OK) {
            if (redirectTo == null) {
                return getJavascriptMensagemOK();
            } else {
                return getJavascriptMensagemOK(redirectTo);
            }
        } else {
            if (this.status == HttpServletResponse.SC_METHOD_NOT_ALLOWED) {
                return getJavascriptMensagemLogin(redirectTo);
            } else {
                return getJavascriptMensagemErro();
            }
        }
    }

    private String getJavascriptMensagemOK() {
        String result =
                "<script>"
                + "$(function(){"
                + "var message = jQuery('<div style=\"z-index: 9999;\"></div>').html('" + this.mensagem + "');"
                + "message.dialog({"
                + "modal: true,"
                + "resizable: false,"
                + "draggable: false,"
                + "buttons: {"
                + "Ok: function() {"
                + "$( this ).dialog( 'close' );"
                + "}"
                + "}"
                + "});"
                + "});"
                + "</script>";
        return result;
    }

    private String getJavascriptMensagemOK(String redirectTo) {
        String result =
                "<script>"
                + "$(function(){"
                + "var message = jQuery('<div style=\"z-index: 9999;\"></div>').html('" + this.mensagem + "');"
                + "message.dialog({"
                + "modal: true,"
                + "resizable: false,"
                + "draggable: false,"
                + "buttons: {"
                + "Ok: function() {"
                + "$( this ).dialog( 'close' );"
                + "}"
                + "},"
                + "close: function(){"
                + "window." + (redirecionarTelaPai ? "top." : "") + "location.href= '" + redirectTo + "';"
                + "}"
                + "});"
                + "});"
                + "</script>";
        return result;
    }

    private String getJavascriptMensagemErro() {
        String result =
                "<script>"
                + "$(function(){"
                + "var message = jQuery('<div style=\"z-index: 9999;\"></div>').html('" + this.mensagem + "');"
                + "message.dialog({"
                + "modal: true,"
                + "resizable: false,"
                + "draggable: false,"
                + "buttons: {"
                + "Ok: function() {"
                + "$( this ).dialog( 'close' );"
                + "}"
                + "},"
                + "close: function(){"
                + "history.go(-1);"
                + "}"
                + "});"
                + "});"
                + "</script>";
        return result;
    }

    private String getJavascriptMensagemLogin(String redirectTo) {
        if (redirectTo == null) {
            redirectTo = CFG.PAGINA_PRINCIPAL;
        }
        String result =
                "<script>"
                + "$(function(){"
                + "var message = jQuery('<div style=\"z-index: 9999;\"></div>').html('" + this.mensagem + "');"
                // message.append(link para tela de login);
                + "message.dialog({"
                + "modal: true,"
                + "resizable: false,"
                + "draggable: false,"
                + "closeOnEscape: false,"
                + "open: function(event, ui) { $('.ui-dialog-titlebar-close', ui.dialog || ui).hide(); },"
                + "buttons: {"
                + "Ok: function() {"
                + "window.top.location.href= 'login?urlDesejada=" + redirectTo + "&msg=" + this.tipoMensagem + "';" // adicionar link para login
                + "}"
                + "}"
                + "}).bind('dialogbeforeclose', function(event, ui) {return false;});"
                + "});"
                + "</script>";
        return result;
    }

    public boolean validarSessao() throws InvalidateException {
        if (request.getSession().isNew()) {
            gerarErroSessaoExpirada();
            return false;
        } else {
            return true;
        }
    }

    public Editor getUsuarioValido() throws InvalidateException {
        Editor editor = (Editor) request.getSession().getAttribute("editor");
        if (editor == null) {
            gerarErroLoginExigido();
            return null;
        } else {
            return editor;
        }
    }

    public Object validarParametroFormulario(String nomeParametro, TipoParametro tipoParametro, MultipartFormHandler form) throws InvalidateException {
        String valorParametro = null;
        try {
            valorParametro = form.getParameter(nomeParametro);
        } catch (UnsupportedEncodingException ex) {
            gerarErroGeral();
        }
        return validarParametro(valorParametro, nomeParametro, tipoParametro);
    }

    public Object validarParametroRequisicaoSimples(String nomeParametro, TipoParametro tipoParametro) throws InvalidateException {
        String valorParametro = request.getParameter(nomeParametro);
        if (tipoParametro == TipoParametro.DATA_HORA) {
            valorParametro += " " + request.getParameter(nomeParametro.replace("data", "hora"));
        }
        return validarParametro(valorParametro, nomeParametro, tipoParametro);
    }

    private Object validarParametro(String valorParametro, String nomeParametro, TipoParametro tipoParametro) throws InvalidateException {
        Object parametro = null;
        if (tipoParametro == TipoParametro.INTEIRO) {
            try {
                parametro = Integer.parseInt(valorParametro);
            } catch (NullPointerException ex) {
                status = HttpServletResponse.SC_BAD_REQUEST;
                mensagem = getMensagemStatus(PARAMETRO_FALTANTE, nomeParametro);
                throw new InvalidateException(mensagem);
            } catch (NumberFormatException ex) {
                status = HttpServletResponse.SC_BAD_REQUEST;
                mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
                throw new InvalidateException(mensagem);
            }
        } else {
            if (tipoParametro == TipoParametro.BOOLEAN) {
                if (valorParametro != null) {
                    parametro = (valorParametro.equalsIgnoreCase("true") ? true : false);
                } else {
                    status = HttpServletResponse.SC_BAD_REQUEST;
                    mensagem = getMensagemStatus(PARAMETRO_FALTANTE, nomeParametro);
                    throw new InvalidateException(mensagem);
                }
            } else {
                if (tipoParametro == TipoParametro.STRING) {
                    if (valorParametro != null && !valorParametro.trim().equalsIgnoreCase("")) {
                        parametro = valorParametro;
                    } else {
                        status = HttpServletResponse.SC_BAD_REQUEST;
                        mensagem = getMensagemStatus(PARAMETRO_FALTANTE, nomeParametro);
                        throw new InvalidateException(mensagem);
                    }
                } else {
                    if (tipoParametro == TipoParametro.DATA_HORA) {
                        if (valorParametro != null) {
                            try {
                                SimpleDateFormat formater = new SimpleDateFormat("dd/MM/yyyy hh:mm");
                                parametro = formater.parse(valorParametro.replaceAll("-", "/"));
                            } catch (ParseException ex) {
                                status = HttpServletResponse.SC_BAD_REQUEST;
                                mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
                                throw new InvalidateException(mensagem);
                            } catch (NumberFormatException ex) {
                                status = HttpServletResponse.SC_BAD_REQUEST;
                                mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
                                throw new InvalidateException(mensagem);
                            } catch (ArrayIndexOutOfBoundsException ex) {
                                status = HttpServletResponse.SC_BAD_REQUEST;
                                mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
                                throw new InvalidateException(mensagem);
                            }
                        } else {
                            status = HttpServletResponse.SC_BAD_REQUEST;
                            mensagem = getMensagemStatus(PARAMETRO_FALTANTE, nomeParametro);
                            throw new InvalidateException(mensagem);
                        }
                    }
                    if (tipoParametro == TipoParametro.DATA) {
                        if (valorParametro != null) {
                            try {
                                SimpleDateFormat formater = new SimpleDateFormat("dd/MM/yyyy");
                                parametro = formater.parse(valorParametro.replaceAll("-", "/"));
                            } catch (ParseException ex) {
                                status = HttpServletResponse.SC_BAD_REQUEST;
                                mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
                                throw new InvalidateException(mensagem);
                            } catch (NumberFormatException ex) {
                                status = HttpServletResponse.SC_BAD_REQUEST;
                                mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
                                throw new InvalidateException(mensagem);
                            } catch (ArrayIndexOutOfBoundsException ex) {
                                status = HttpServletResponse.SC_BAD_REQUEST;
                                mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
                                throw new InvalidateException(mensagem);
                            }
                        } else {
                            status = HttpServletResponse.SC_BAD_REQUEST;
                            mensagem = getMensagemStatus(PARAMETRO_FALTANTE, nomeParametro);
                            throw new InvalidateException(mensagem);
                        }
                    }
                }
            }
        }
        return parametro;
    }

    public boolean validarTamanhoArquivo(FileItem arquivo, int tamanho) throws InvalidateException {
        if (arquivo.getSize() <= 0) {
            gerarErroArquivoVazio();
            return false;
        } else {
            if ((tamanho != 0) && arquivo.getSize() > tamanho) {
                status = HttpServletResponse.SC_BAD_REQUEST;
                mensagem = getMensagemStatus(ARQUIVO_GRANDE, "" + tamanho);
                throw new InvalidateException(mensagem);
            } else {
                return true;
            }
        }
    }

    public void validarMultipart(HttpServletRequest request) throws InvalidateException {
        try {
            if (form.isMultipart(request)) {
                return;
            } else {
                gerarErroServidor();
            }
        } catch (FileUploadException ex) {
            gerarErroServidor();
        }
    }

    public MultipartFormHandler getMultipartHandler() throws InvalidateException {
        try {
            form = new MultipartFormHandler();
            return form;
        } catch (FileUploadException ex) {
            gerarErroServidor();
            return null;
        }
    }

    public void gerarStatusOK(String mensagem) {
        this.status = HttpServletResponse.SC_OK;
        this.mensagem = mensagem;
    }

    public void gerarStatus(int status, int tipoMensagem) throws InvalidateException {
        this.status = status;
        this.mensagem = getMensagemStatus(tipoMensagem);
        throw new InvalidateException(mensagem);
    }

    public void gerarErroServidor() throws InvalidateException {
        tipoMensagem = ERRO_SERVIDOR;
        gerarStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, tipoMensagem);
    }

    public void gerarErroSessaoExpirada() throws InvalidateException {
        tipoMensagem = SESSAO_EXPIRADA;
        gerarStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED, tipoMensagem);
    }

    public void gerarErroLoginExigido() throws InvalidateException {
        tipoMensagem = LOGIN_REQUIRED;
        gerarStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED, tipoMensagem);
    }

    public void gerarErroGeral() throws InvalidateException {
        tipoMensagem = ERRO_GERAL;
        gerarStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, tipoMensagem);
    }

    public void gerarErroBD() throws InvalidateException {
        tipoMensagem = ERRO_BD;
        gerarStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, tipoMensagem);
    }

    public void gerarErroPadrinhoInexistente() throws InvalidateException {
        tipoMensagem = PADRINHO_INEXISTENTE;
        gerarStatus(HttpServletResponse.SC_BAD_REQUEST, tipoMensagem);
    }

    public void gerarErroCasamentoInexistente() throws InvalidateException {
        tipoMensagem = CASAMENTO_INEXISTENTE;
        gerarStatus(HttpServletResponse.SC_BAD_REQUEST, tipoMensagem);
    }

    public void gerarErroExcluirFotoInexistente() throws InvalidateException {
        tipoMensagem = EXCLUIR_FOTO_INEXISTENTE;
        gerarStatus(HttpServletResponse.SC_BAD_REQUEST, tipoMensagem);
    }

    public void gerarErroArquivoVazio() throws InvalidateException {
        tipoMensagem = ARQUIVO_VAZIO;
        gerarStatus(HttpServletResponse.SC_BAD_REQUEST, tipoMensagem);
    }

    public void gerarErroGravarArquivo() throws InvalidateException {
        tipoMensagem = ERRO_GRAVAR_ARQUIVO;
        gerarStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, tipoMensagem);
    }

    public void gerarErroPermissaoNegada() throws InvalidateException {
        tipoMensagem = PERMISSAO_NEGADA;
        gerarStatus(HttpServletResponse.SC_FORBIDDEN, tipoMensagem);
    }

    public void gerarErroUsuarioSenhaIncorreto() throws InvalidateException {
        tipoMensagem = USUARIO_SENHA_INCORRETOS;
        gerarStatus(HttpServletResponse.SC_FORBIDDEN, tipoMensagem);
    }

    public void gerarErroParametroInvalido(String nomeParametro) throws InvalidateException {
        status = HttpServletResponse.SC_BAD_REQUEST;
        mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeParametro);
        throw new InvalidateException(mensagem);
    }

    public void gerarErroEntidadeNaoEncontrada(String nomeEntidade) throws InvalidateException {
        status = HttpServletResponse.SC_BAD_REQUEST;
        mensagem = getMensagemStatus(PARAMETRO_INVALIDO, nomeEntidade);
        throw new InvalidateException(mensagem);
    }
    
    public void gerarErroConviteVazio() throws InvalidateException {
        gerarStatus(HttpServletResponse.SC_BAD_REQUEST, CONVITE_VAZIO);
    }

    public static String getMensagemStatus(int tipoMensagem) {
        return getMensagemStatus(tipoMensagem, null);
    }

    private static String getMensagemStatus(int tipoMensagem, String parametro) {
        switch (tipoMensagem) {
            case SESSAO_EXPIRADA:
                return "Sua sessão expirou! Você precisa realizar login para executar essa operação.";
            case LOGIN_REQUIRED:
                return "Você precisa estar logado para fazer essa operação!<br />Efetue o login para prosseguir.";
            case PARAMETRO_FALTANTE:
                return "O parâmetro \"" + parametro + "\" é necessário para executar essa operação! Se o problema persistir, entre em contato conosco.";
            case PARAMETRO_INVALIDO:
                return "O parâmetro \"" + parametro + "\" não é válido.";
            case ERRO_SERVIDOR:
                return "Ocorreu um erro ao gravar o arquivo em nossos servidores. Por favor, tente novamente. Se o problema persistir, entre em contato com nossa equipe.";
            case PERMISSAO_NEGADA:
                return "Você não tem permissão para editar esse casamento.";
            case ERRO_BD:
            case ERRO_GERAL:
                return "Ocorreu um erro durante o processamento da requisição. Por favor, tente novamente. Se o problema persistir, entre em contato com nossa equipe.";
            case ARQUIVO_VAZIO:
                return "O arquivo que você está tentando enviar está vazio!";
            case ARQUIVO_GRANDE:
                return "O arquivo que você está tentando enviar é maior que o permitido (" + parametro + ")!";
            case CASAMENTO_INEXISTENTE:
                return "O casamento que você está tentando editar não existe em nosso sistema. Caso tenha certeza que ele existe, entre em contato com nossa equipe.";
            case ENTIDADE_INEXISTENTE:
                return "O " + parametro + " que você está tentando editar não existe em nosso sistema. Caso tenha certeza que ele exista, entre em contato com nossa equipe.";
            case PADRINHO_INEXISTENTE:
                return "O padrinho que você está tentando editar não foi encontrado nesse casamento.";
            case ERRO_GRAVAR_ARQUIVO:
                return "Ocorreu um erro ao gravar o arquivo em nossos servidores. Por favor, tente novamente. Se o problema persistir, entre em contato com nossa equipe.";
            case EXCLUIR_FOTO_INEXISTENTE:
                return "A foto que você está tentando excluir não existe em nosso sistema.";
            case EMAIL_CADASTRADO:
                return "Este endereço de e-mail já está cadastrado em nossos sistemas! Tente utilizar outro.";
            case USUARIO_SENHA_INCORRETOS:
                return "Seu endereço de e-mail ou senha estão incorretos.<br />Verifique se os está digitando corretamente.";
            case CONVITE_VAZIO:
                return "Você precisa adicionar pelo menos um nome para enviar um convite!";
            case LOGIN_PARA_COMPRA:
                return "Para enviar o presente aos noivos, você precisa estar logado ou realizar o cadastro. É rapidinho!";
            default:
                return "OK";
        }
    }
    public static final int ERRO_GERAL = 0;
    public static final int SESSAO_EXPIRADA = 1;
    public static final int LOGIN_REQUIRED = 2;
    public static final int PARAMETRO_FALTANTE = 3;
    public static final int PARAMETRO_INVALIDO = 4;
    public static final int ERRO_SERVIDOR = 5;
    public static final int PERMISSAO_NEGADA = 6;
    public static final int ERRO_BD = 7;
    public static final int ARQUIVO_VAZIO = 8;
    public static final int ARQUIVO_GRANDE = 9;
    public static final int CASAMENTO_INEXISTENTE = 10;
    public static final int PADRINHO_INEXISTENTE = 11;
    public static final int ERRO_GRAVAR_ARQUIVO = 12;
    public static final int EXCLUIR_FOTO_INEXISTENTE = 13;
    public static final int ENTIDADE_INEXISTENTE = 14;
    public static final int EMAIL_CADASTRADO = 15;
    public static final int USUARIO_SENHA_INCORRETOS = 16;
    public static final int CONVITE_VAZIO = 17;
    public static final int LOGIN_PARA_COMPRA = 18;
}
